home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 21
/
Aminet 21 (1997)(GTI - Schatztruhe)[!][Oct 1997].iso
/
Aminet
/
comm
/
cnet
/
ansi_pack.lha
/
ANSI_Rexx
< prev
next >
Wrap
Text File
|
1996-12-04
|
35KB
|
721 lines
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Using & Interpreting ANSI Codes in Your ARexx Creations! v1.00
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Alright, a few of you out there(you know who you are), have been throwing
hints my way about the actual USAGE of ANSI codes in ARexx for CNet Amiga,
so let's have some fun!
Of all the available ANSI codes, the following can(and SHOULD) be used to
the hilt in anything you write! ;-)
~[?;?;?m ~[?;?H ~[?A ~[?B ~[?C ~[?D ~[s ~[u
These codes, coupled with some CNet ARexx Primitives(namely GETCHAR,
MAYGETCHAR, TRANSMIT, and SENDSTRING) are all you really need to get your
own programs using ANSI both effectively and efficiently. It should also be
noted that the majority of the CNet Primitives used in this discussion are
also part of the "ABBEREXX" standard, to which MANY Amiga BBS programs
adhere to, so these explanations may prove useful for Non-CNet SysOps as
well.
Before continuing, please take a moment to install the following little
scripts, which I have found to be extremely helpful in the creation of my
ARexx projects, and you might as well:
NOTE: If you'd like to SKIP the following sections and get right to the
ANSI-meat portion of this document, search for STARTING WITH ANSI!
~~~~~~~~~~~~~~~~~~
RunARexx
~~~~~~~~
Copied somewhere on your system, like in DOORS:, you can then create the
following line in your BBSMENU file, to the bottom of Menu # 3:
RUNA, RUNArexx `31 | {#0doors:RunARexx}
^ ^
Who Can Use RUNA? Control-Q character.
This command allows you to "test drive" any ARexx program of your choosing
from within CNet proper, just like CNet's internal RUN command can do for any
CNetC programs. You can either type:
CNet: runa<enter>
- Then type in a <path>filename, or...
CNet: runa <path>filename
Provided the file exists at stated path, it will be executed, however you
will be notified if the file is missing.
NewDoor & TestDoor
~~~~~~~ ~~~~~~~~
"NewDoor" is an Arexx template to get you started, while "TestDoor" is
a file you can run from anywhere on your system by adding the following to
the end of Menu # 3 in your BBSMENU command:
TEST `31 | {#0doors:TestDoor}
Whenever you feel like "experimenting" with a new fragment of Arexx code,
copy it into the "TestDoor" script, then type TEST from anywhere on your BBS,
even while inside one of CNet's editors(using the .* or CTRL-C commands)!
These files can act as the "basic framework" for any ARexx creations you
create. They are both virtually identical. The TOP portion of each file holds
the following lines:
/**************************************************************************\
$VER: Program Name, v0.00 (DD-MMM-YY) by Handle of BBS Name!
\**************************************************************************/
options results;signal on SYNTAX;signal on ERROR;signal on IOERR
/*ver=word(sourceline(2),?);a=word(sourceline(2),?);parse var a "("vdate")"*/
tr=transmit;se=sendstring;gc=getchar;gu=getuser;gs=getscratch;mg=maygetchar
a='rexxsupport.library';if ~show('l',a) then if ~addlib(a,0,-30) then exit
You should modify the 2nd and 5th lines above to reflect the name and
version of the file you are creating. If you REMOVE the /* and */ from line
5, then replace the two "?"'s on the line with the word position of the
version number and date of creation, you'll then have two variables you can
use anywhere in your program when you want to print the VERSION or DATE of
LAST modification. In the above example, you'd replace the first ? with a 4,
because the version number(v0.00) is the FOURTH word on the line. Likewise,
you'd replace the second ? with a 5, as the date(DD-MMM-YY) is the FIFTH word
to appear on line 5. Depending on how you set up line 2, these numbers will
change, so be sure to update them correctly, before attempting to use the
"ver" and "vdate" variables yourself. A line like the following shows you how
these variables could be used in a TRANSMIT variable:
transmit "My Program, "ver", last modified on: "vdate"!"
The 6th and 7th lines listed above offer you a bit more flexability in
your coding. The 6th line creates a series of command "aliases", which you
can then opt to use INSTEAD of typing the entire command. For instance, if a
program you create uses the TRANSMIT command 50 times, the entire word of
TRANSMIT would appear, versus just the two characters TR. So what? Well, when
using TRANSMIT, it's costing you 8 bytes, while if you use TR, it only costs
you 2 bytes. Again, so?!? Use the above example. If TRANSMIT is used 50 times
in your program, and if using TR saves you 6 bytes each time, 50x6=300 bytes.
Now, you continue to do this with the other aliases: SE, GC, GU, GS, and
MG, then do the math, oftentimes this can lead to anywhere from 3K to 10K
savings. You should REMOVE any aliases you are NOT using, and create any NEW
aliases that YOU find helpful. (Keep in mind, however, that if you'll only be
using a given command once or twice, then it won't help to create an alias,
as in these instances, it could result in your program actually taking up
MORE bytes than it really could).
The 7th line simply makes the ARexx Support Library available to you. If
this line is MISSING, and you attempt to use a support command, you'll run
into problems later on. The following commands are stored in this library, so
if your program is NOT using any of these commands, you could DELETE the 7th
line from the NewDoor program:
ALLOCMEM, BADDR, CLOSEPORT, DELAY, DELETE, FORBID, FREEMEM, GETARG,
GETPKT, MAKEDIR, NEXT, NULL, OFFSET, OPENPORT, PERMIT, RENAME, REPLY,
SHOWDIR, SHOWLIST, STATEF, TYPEPKT, and WAITPKT.
I'd like to further note that the "dos" type commands listed above, like
DELETE, MAKEDIR, and RENAME are actual ARexx Primitives included as new Arexx
commands, and are NOT the same as if you call one of the DOS commands using
the same name. For example:
address command "c:delete ram:test"
and
call DELETE("ram:test")
Both do the same thing, however the ADDRESS command is internal to the
main "rexxsyslib.library", so does NOT make use of the support library, while
using the DELETE() function DOES use the "rexxsupport.library".
Alright, the BOTTOM of both scripts looks like this:
exit
CHECK:;if ARG() & ARG(1)~='###PANIC' then return ARG(1)
getcarrier;if result='TRUE' then if ARG() then return ARG(1);else return
/* Place any "cleanup" or "reenable" code here, before exiting! */
logentry 'Lost Carrier!!';bufferflush;exit
SYNTAX:;ERROR:;IOERR:;e1='n1 Error: 'rc' ('errortext(rc)')'
e2=' Line: 'left(sigl,4)'File:';gu 1311992;a=result;gu 1311960
b=result;c='"'a||b', 'ver'"';e2=e2' 'c;tr e1;tr e2;logentry e1
logentry e2;e=translate(sourceline(sigl),"\{","");do while e~=''
e3='Source: 'left(e,37);tr e3;logentry e3;e=substr(e,38);end;bufferflush
/**************************************************************************\
\****************************************** BBS Name (AAA)/PPP-SSSS *******/
The CHECK: routine is the latest "loss of carrier" check routine that
I've been using. To use the routine, simple CALL it whenever you want to
check for carrier, preferably whenever you're awaiting input from the user,
as in this example:
sendstring "Do what now? " ; getchar ; a=result ; call CHECK
You don't have to go OVERBOARD with your usage of this command, but you
DO want to make sure you include it anywhere that might put the user in a
dead-lock loop(for instance, if you're sking the user to hit 1, 2, or 3, and
if your program will continually ask for one of these keys UNTIL one of them
has been pressed, if the user loses carrier at this prompt, the script will
put itself into a "dead-lock" and you'll have a serious problem.
While creating scripts, if you discover a script that IS in a dead-lock,
there's a program called HI, located in the "Sys:Rexxc/" directory that you
can use to HALT or STOP the Arexx program, however further note that using
this command halts ALL currently running ARexx programs, so if users on other
ports are also using ARexx programs, they'll be kicked out of THEIR programs
as well.
Lastly, note the comment line in the CHECK: routine:
/* Place any "cleanup" or "reenable" code here, before exiting! */
If there is any DATA that would need to be saved in order to save the
integrity of what the user was doing, then place calls to your SAVE routines
within this routine as well. Also, if your program MODIFIES one of the user's
settings(for instance, if it turns the MORE mode OFF or MUFFLES the user from
all other users), then be sure to REVERSE the process in this routine as well,
so that if a user was NOT muffled when going INTO your program, and they lose
carrier, the next time they log on, they should STILL NOT be muffled.
The SYNTAX:;ERROR:;IOERR: routine is the latest error-check routine I've
been using myself, and is actually quite powerful in itself. Not only will
the user(or you) be alerted as soon as a "capturable" error has occurred, but
the exact same message will be appended to either your "calls" log, or an
"ARexxSays" log, if you have one defined. The format of the output is such
that it will look as readable as possible when presented in the log. All MCI
commands located on the line are changed to their \{ non-destructive states,
so you can be sure to see the line as it would appear if you were editing it
in a text editor.
The comment lines at the bottom of the listing are included only as a
means of insuring the entire file is intact. You can put your BBS's name in
this comment field if you so wish.
When using the "NewDoor" file, train yourself to do the following:
1. Load the "NewDoor" file into your text editor.
2. Change the 2nd and 5th lines as needed.
3. Now SAVE AS the file as the NAME you'd like to give your creation.
4. NOW start creating your coding.
This way, you won't discover later on that you no longer HAVE the NewDoor
template to use, because it was morphed into your latest ARexx creation. If
using a Dock-type program, like Tool Manager, you can even opt to create an
instant way to launch both of these programs. For me, because I create LOTS
of different programs, I have them as buttons on a "Programming Dock" on my
WorkBench screen, so creating a NEW program, or testing some new theory is
only a mouse-click away!
-----------------------------------------------------------------------------
STARTING WITH ANSI!
~~~~~~~~~~~~~~~~~~
Let's start with a look at the Amiga Keyboard. It is possible to capture
keypresses from NUMEROUS additional keys, besides the number and letter keys.
This includes the cursor-arrow keys, the escape key, the backspace key, the
delete key, the enter/return key, the tab key, as well as any/all qualified
keystrokes(those gotten while first holding SHIFT, CTRL, ALT, or a combination
of these).
Among those keystrokes NOT able to be "caught" by ARexx include the ten
function keys(and their qualified states), the help key, the caps lock key,
and any qualified keystrokes using the left or right Amiga Command keys.
The Numeric Keypad to the right of the main keyboard maps to the same
keystrokes as those keys shown on the face of each key. (Meaning the 7 acts
the same as a 7 on the main keyboard, however the `home' function cannot be
mapped to it's own value through Arexx, nor can any of the other `fronts').
For our first look at ARexx and ANSI, let's explore the keyboard. Type or
copy the following into the included "TestDoor" script, then use the TEST
command to execute the script:
START:
se "Press any key now(press Q to quit): "
gc ; k=result ; tr k
if k="Q" then exit
signal START
The above script will loop forever, until such a time as you press the "Q"
key on your keyboard. After using it for a bit, you'll notice that there are
many keys you can press which return visual(printable) results, which can all
be used within your ARexx creations.
While still running the above program, try pressing the following keys:
enter, tab, backspace, ctrl-q, ctrl-s, ctrl-y
There are others as well, but you get my drift, right? :-) These keystrokes
DID return a value(as shown by the prompt advancing a line), however in their
current state, the returned results are unusable. Now try pressing the cursor
arrow keys, specifically noting what happens to the prompt(especially the next
one printed after pressing an arrow key). Did you notice the "P" in the text
for the prompt was suppressed? Remember this behavior for a bit. Lastly, try
typing an "A" on the keyboard. Did it print an UPPER or lowercase letter? See
if you can get it to print the opposite case letter.
As shown above, the initial script "sorta" works, and in fact, works GREAT
for some applications, but not for others, so let's change the script a bit.
Try copying the following into your "TestDoor" script ABOVE the script we
were working with earlier:
START2:
se "Press any key now(press Q to quit): "
do until k~="NOCHAR" ; mg ; k=result ; end
tr c2d(k) ; if k="q" then exit
signal START2
After running this one for awhile, you'll notice somthing VERY strange.
Instead of seeing the printable characters you WANTED, you're seeing NUMBERS,
nothing but NUMBERS. Now, before you get in a tizzy, try those "bad" keys
again. Remember:
enter, tab, backspace, ctrl-q, ctrl-s, ctrl-y
Also, see what happens when you press "A", "SHIFT-A", "CTRL-A", etc. I'm
hoping you're noticing that even though it's NUMBERS being returned, they are
all UNIQUE from each other.
Now, try typing the cursor arrows again. Notice the output this time is
NUMBERS again, but did you ALSO notice that it printed THREE numbers, instead
of ONE, as all the other keystokes did? Are you seeing what's happening yet?
No? Would it help if I told you that all these NUMBERS it's printing right
now are the ASCII equivalents of the actual characters? If you were to look
through an ASCII chart, here's what you'd find for the three numbers that are
printed when you press the UP cursor arrow:
Press any key now(press Q to quit): 27 <--- An ESCape code.
Press any key now(press Q to quit): 91 <--- An open bracket ([).
Press any key now(press Q to quit): 65 <--- A capital letter A.
In other words: ESC [ A
Does THAT look a bit more familiar?!? hehe I should hope so. You'll notice
similar strings of numbers for the other arrows:
27-91-66 <--- DOWN cursor arrow.
27-91-67 <--- RIGHT cursor arrow.
27-91-68 <--- LEFT cursor arrow.
Before we continue, try pressing the ESCape key while running the script:
Press any key now(press Q to quit): 27
Note that it returns the same 27 that was also used in the cursor keystroke
lists. So, what does all this MEAN? Well, it means that it's possible for us
to capture these keystrokes, however depending on WHICH keystrokes we want,
we have to go about GETTING them through different means.
Let's take a look at a script with a bit more meat. Copy the following to
your "TestDoor" script ABOVE the START2: routine we just finished with:
KEYS1:
tr "Press some keys now..."
do forever until k="q"
mg ; k=result ; kk="" ; if k="NOCHAR" then iterate
if c2d(k)=27 then do 2 ; mg ; kk=result ; end
select
when c2d(k)=27 & kk="NOCHAR" then tr "You pressed the ESCape key..."
when kk="A" then tr "You pressed the UP cursor arrow..."
when kk="B" then tr "You pressed the DOWN cursor arrow..."
when kk="C" then tr "You pressed the RIGHT cursor arrow..."
when kk="D" then tr "You pressed the LEFT cursor arrow..."
when c2d(k)=13 then tr "You pressed the ENTER key..."
when c2d(k)=9 then tr "You pressed the TAB key..."
when c2d(k)=127 then tr "You pressed the DELETE key..."
when c2d(k)=8 then tr "You pressed the BACKSPACE key..."
when c2d(k)=32 then tr "You pressed the SPACEBAR key..."
otherwise tr "You pressed the "k" key..."
end
end
exit
The above routine will successfully capture ANY of the "available" keys.
You'll notice that the MAYGETCHAR command has been used solely in the routine,
however it could be slightly rewritten to use the GETCHAR command instead:
KEYS2:
tr "Press some keys now..."
do forever until k="Q"
gc ; k=result ; kk="" ; if c2d(k)=27 then do 2 ; gc ; kk=result ; end
select
when c2d(k)=27 & kk="" then tr "You pressed the ESCape key..."
when kk="A" then tr "You pressed the UP cursor arrow..."
when kk="B" then tr "You pressed the DOWN cursor arrow..."
when kk="C" then tr "You pressed the RIGHT cursor arrow..."
when kk="D" then tr "You pressed the LEFT cursor arrow..."
when c2d(k)=13 then tr "You pressed the ENTER key..."
when c2d(k)=9 then tr "You pressed the TAB key..."
when c2d(k)=127 then tr "You pressed the DELETE key..."
when c2d(k)=8 then tr "You pressed the BACKSPACE key..."
when c2d(k)=32 then tr "You pressed the SPACEBAR key..."
otherwise tr "You pressed the "k" key..."
end
end
exit
You'll notice the KEYS2 routine is a bit shorter than the KEYS1 routine,
however KEYS2 lacks the ability to map UPPER versus lowercase letter keys.
The MAYGETCHAR command returns the ACTUAL key pressed, which means "a" is
returned if you press the "a" key, while "A" is returned if "SHIFT-A" was
pressed.
Another nice advantage to using MAYGETCHAR is that it means precisely what
it's name implies, the Amiga MAY get a character, or it MAY NOT. If a key was
NOT caught, MAYGETCHAR returns the text string "NOCHAR". Well, you're most
probably thinking, "So what?", right? Well, not HAVING to wait for a keypress
can come in REAL handy when writing programs. For instance, let's take a GAME
for an example. I'm thinking of the game Tetris. If you opt NOT to move one
of the shapes to the left or the right, and you opt NOT to rotate the shape,
what happens to the shape? Does it just sit there WAITING for you to tell it
what you want it to do? Yeah, I wish! No, it continues to move DOWN the game
screen. It's this same MAYGETCHAR type of operation that allows a game like
Tetris to do that:
SHAPE:
- Display the shape.
MOVE:
- Did user hit LEFT or RIGHT?
- Yes - then move the shape...
- No - then continue...
- Did user ROTATE the shape?
- Yes - then rotate the shape...
- No - then continue...
- Move the shape DOWN one line!
- Did shape hit bottom yet?
- Yes - then go to SHAPE:
- No - then go back to MOVE:
What's more, you could also have things like a SCORE being updated while
waiting for the keystrokes. You could display the NEXT shape or two, etc.
without having to WAIT for a keystroke.
Now, you have to be a BIT careful here, as you don't want to spend TOO
MUCH time doing other things, else you'll lose the seamless flow to the
end result you're looking to accomplish.
Alright, so we know HOW to get the characters from the keyboard, but how
do we then create an ARexx routine to USE these characters? Let's take yet
another ARexx routine. Copy this one ABOVE the KEYS1 (or KEYS2) routine you
were last working with, then run the "TestDoor" script again:
tr "f1.--.--.--.--.--.--.--.--.--.--."
do 9;tr "| | | | | | | | | | |"
tr "|--+--+--+--+--+--+--+--+--+--|";end
tr "| | | | | | | | | | |"
tr "`--^--^--^--^--^--^--^--^--^--'"
row=1 ; col=1
MOVE:
se ""row*2";"col*3-1"H"
gc ; k=result ; kk="" ; if c2d(k)=27 then do 2 ; mg ; kk=result ; end
if c2d(k)=27 & kk="NOCHAR" then do ; se "1HExiting..." ; exit ; end
if c2d(k)=13 then do ; se "1HRow: "row", Column: "col ; exit ; end
if kk="A" & row>1 then row=row-1
if kk="B" & row<10 then row=row+1
if kk="C" & col<10 then col=col+1
if kk="D" & col>1 then col=col-1
signal MOVE
This routine starts by printing a simple 10x10 grid, with an Ascii Frame
around it. The MOVE: routine uses the same techniques discussed above, with
the addition of two variables, "row" and "col". These variables have their
values changed, dependent upon which cursor-arrow keys you press. This is
evident in the program by the cursor moving around within the grid. If we
press ESC, we can EXIT the program, but if we press ENTER, we exit as well
as being told WHICH row and column we were IN before we left.
This is a fairly simple grid technique with some limitations. For one, it
uses finite borders. This means that once we reach one of the borders, that's
as far as the current script will allow us to go. With some slight changes to
the four "if kk=..." lines, we can make this movement more powerful:
if kk="A" then do ; row=row-1 ; if row<1 then row=10 ; end
if kk="B" then do ; row=row+1 ; if row>10 then row=1 ; end
if kk="C" then do ; col=col+1 ; if col>10 then col=1 ; end
if kk="D" then do ; col=col-1 ; if col<1 then col=10 ; end
With the above changes, the script will allow the cursor to wrap around
the borders, which allows for a bit more freedom of movement.
Another problem with the script occurs if we give some thought as to WHO
might be using the program. Some IBM and Amiga users do not have separate
arrow keys on their keyboards. These users rely on using the Numeric Keypad's
arrow keys, which reside on the 2, 4, 6, and 8 keys. We could further modify
the above lines to take these people into consideration as well:
if k="8" | kk="A" then do ; row=row-1 ; if row<1 then row=10 ; end
if k="2" | kk="B" then do ; row=row+1 ; if row>10 then row=1 ; end
if k="6" | kk="C" then do ; col=col+1 ; if col>10 then col=1 ; end
if k="4" | kk="D" then do ; col=col-1 ; if col<1 then col=10 ; end
Not too much extra to satisfy these users, huh? Well, what else could the
"little script that could" use? How about getting rid of the cursor? If we
change the first few lines of the MOVE: routine to use the MAYGETCHAR command,
instead of the GETCHAR command, we can solve this problem:
MOVE:
se ""row*2";"col*3-1"H"
do until k~="NOCHAR" ; mg ; k=result ; end ; kk=""
if c2d(k)=27 then do 2 ; mg ; kk=result ; end
However, if you try these changes, you'll notice another problem, as there
is no way of knowing WHERE you are, so we need a VISIBLE character to act as
our prompt character. This can be accomplished by adding 1 character to the
first line of the MOVE: routine:
se ""row*2";"col*3-1"H>"
Note the addition of the > character as the second last character on the
line above. This gives us a better looking cursor over the "big block", but
because this is a PRINTABLE character, you'll notice a trail of >'s follow
you as you traverse the grid. To fix this problem, we need to add one line
right above those "if kk=..." lines, like this:
tr ""row*2";"col*3-1"H "
Note that in the above line, a SPACE appears where the > appeared in the
line that printed the prompt. What we're doing is using the ANSI positioning
codes to print the cursor, print a space OVER the cursor, modify the position
of the cursor, then reprint the cursor. Here's what the entire routine should
now look like:
tr "f1.--.--.--.--.--.--.--.--.--.--."
do 9;tr "| | | | | | | | | | |"
tr "|--+--+--+--+--+--+--+--+--+--|";end
tr "| | | | | | | | | | |"
tr "`--^--^--^--^--^--^--^--^--^--'"
row=1 ; col=1
MOVE:
se ""row*2";"col*3-1"H>"
do until k~="NOCHAR" ; mg ; k=result ; end ; kk=""
if c2d(k)=27 then do 2 ; mg ; kk=result ; end
if c2d(k)=27 & kk="NOCHAR" then do ; se "1HExiting..." ; exit ; end
if c2d(k)=13 then do ; se "1HRow: "row", Column: "col ; exit ; end
tr ""row*2";"col*3-1"H "
if k="8" | kk="A" then do ; row=row-1 ; if row<1 then row=10 ; end
if k="2" | kk="B" then do ; row=row+1 ; if row>10 then row=1 ; end
if k="6" | kk="C" then do ; col=col+1 ; if col>10 then col=1 ; end
if k="4" | kk="D" then do ; col=col-1 ; if col<1 then col=10 ; end
signal MOVE
Well, there you have it! It's actually not that hard to do. Now, there are
some "extras" you might want to toss into a routine like the above. Perhaps
you'd like to be able to "drop" something where the cursor was located, maybe
when the user presses their ENTER keys or something. Again, nothing more than
a slight modification to an existing line above, in this case the line that
starts with "if c2d(k)=13 then..."
if c2d(k)=13 then do ; se ""row*2";"col*3"H#" ; signal MOVE ; end
The above change will allow you to place a # character to the RIGHT of the
> prompt, whenever you press your ENTER key. Note, however, that once the # is
placed, it's there for GOOD. To REMOVE it, you'd have to either define a 2nd
keystroke to remove/lift the piece, or else create an arrayed variable that
would house the contents of each "spot" within the grid.
I'll shy away from pursuing that any farther, as that's getting a bit more
into Game Theory, instead of ANSI coding, but you get the general idea!
Alright, so what ELSE is there to ANSI coding in ARexx? Well, how about the
creation of an AnsiARexx editor, which is used in exactly the same way as one
of CNet's VDE editors? This is yet another feat for the serious ANSI-ARexx
coder. Let's take a look at a fairly simple AnsiARexx editor, which can be
used to modify your mailing address:
gu 3 ; realname=result ; gu 6 ; street=result
gu 4 ; citystate=result ; gu 5 ; zip=result
kb.1=" Real Name:" ; kb.2="Street Address:"
kb.3=" City, State:" ; kb.4=" Zip Code:"
tr "f1z4c7 Simple AnsiARexx VDE Editor z0n1"
tr "z4c7 Real Name:z0 c3"realname
tr "z4c7Street Address:z0 c3"street
tr "z4c7 City, State:z0 c3"citystate
tr "z4c7 Zip Code:z0 c3"zip
kb=1 ; kbt=4
EDIT:
se ""kb+2";1Hz7c4"kb.kb"z0q1"
do until k~="NOCHAR" ; mg ; k=result ; end ; kk=""
if c2d(k)=27 then do 2 ; mg ; kk=result ; end
if c2d(k)=27 & kk="NOCHAR" then do ; tr "1HExiting..." ; exit ; end
se ""kb+2";Hz4c7"kb.kb"z0"
if kk="A" then do ; kb=kb-1 ; if kb<1 then kb=kbt ; end
if kk="B" then do ; kb=kb+1 ; if kb>kbt then kb=1 ; end
signal EDIT
The above code initially reads in your current values, creates a set of
Ansi buttons(the kb. array), as well as setting up two pointers, kb, which
is used to specify which button will be initially highlighted, and kbt which
tells the script the total number of buttons defined. The EDIT: routine uses
the same techniques we've already seen, except instead of printing the one
character > prompt, we're printing the kb. button. Only two cursor keys have
been defined, as there's only one column of data. The UP and DOWN arrows can
be used to move the highlighted button up or down and the ESCape key will
exit the editor.
To actually EDIT the data, we need to define what the ENTER key should do,
based on the value of the kb variable, as that will point at WHICH button was
highlighted when you pressed ENTER. The following code is placed BELOW the
`if kk="B"...' line above:
if c2d(k)=13 then do
if kb=1 then do ; se ""kb+2";17Hr1c3L1305640 #"realname"}I20 34}"
gu 70;realname=result;signal EDIT;end
if kb=2 then do ; se ""kb+2";17Hr1c3L1305640 #"street"}I20 30}"
gu 70;street=result;signal EDIT;end
if kb=3 then do ; se ""kb+2";17Hr1c3L1305640 #"citystate"}I20 22}"
gu 70;citystate=result;signal EDIT;end
if kb=4 then do ; se ""kb+2";17Hr1c3L1305640 #"zip"}I20 10}"
gu 70;zip=result;signal EDIT;end
end
As you can see, the above bit of code is almost as big as the EDIT: routine
itself. I didn't say it would be short! hehe I'm using the {L } MCI command to
load the data into the "line input buffer". The {I20 } MCI command is used to
get a line of input from the user. The "20" is the MCI Environment setting,
and actually stands for 4+16. The 4 means to start with the line input buffer,
and the 16 means to make the first character of every word entered UPPER case.
As shown, the above is a 90% duplicate of the CNetC VDE editors. CNet's
internal VDE editors do two more things: they show the max length of input
possible, while editing a field, and they utilize a "smart" save feature. The
following is the complete version of this editor:
gu 3 ; realname=result ; gu 6 ; street=result
gu 4 ; citystate=result ; gu 5 ; zip=result
kb.1=" Real Name:" ; kb.2="Street Address:"
kb.3=" City, State:" ; kb.4=" Zip Code:"
tr "f1z4c7 Simple AnsiARexx VDE Editor z0n1"
tr "z4c7 Real Name:z0 c3"realname
tr "z4c7Street Address:z0 c3"street
tr "z4c7 City, State:z0 c3"citystate
tr "z4c7 Zip Code:z0 c3"zip
kb=1 ; kbt=4 ; save=0
EDIT:
se ""kb+2";1Hz7c4"kb.kb"z0q1"
do until k~="NOCHAR" ; mg ; k=result ; end ; kk=""
if c2d(k)=27 then do 2 ; mg ; kk=result ; end
if c2d(k)=27 & kk="NOCHAR" then signal SAVE
se ""kb+2";Hz4c7"kb.kb"z0"
if kk="A" then do ; kb=kb-1 ; if kb<1 then kb=kbt ; end
if kk="B" then do ; kb=kb+1 ; if kb>kbt then kb=1 ; end
if c2d(k)=13 then do
if kb=1 then do ; se ""kb+2";17Hz3L1305640 #"realname"}s"
se left("",34)"uz3c4I20 34}";gu 70;a=result;save=(a~=realname)
se "z0c3u"left(a,34);realname=a;signal EDIT;end
if kb=2 then do ; se ""kb+2";17Hz3L1305640 #"street"}s"
se left("",30)"uz3c4I20 30}";gu 70;a=result;save=(a~=street)
se "z0c3u"left(a,30);street=a;signal EDIT;end
if kb=3 then do ; se ""kb+2";17Hz3L1305640 #"citystate"}s"
se left("",22)"uz3c4I20 22}";gu 70;a=result;save=(a~=citystate)
se "z0c3u"left(a,22);citystate=a;signal EDIT;end
if kb=4 then do ; se ""kb+2";17Hz3L1305640 #"zip"}s"
se left("",10)"uz3c4I20 10}";gu 70;a=result;save=(a~=zip)
se "z0c3u"left(a,10);zip=a;signal EDIT;end
end
signal EDIT
SAVE:
if save=0 then tr "1HNo changes made... Exiting..."
else tr "1HChanges Made! Data automatically SAVED, then exit..."
exit
I won't give you the actual SAVE coding, as I want this to be an example
only. You should be able to create the SAVE code yourself, if you actually
WANTED to use this editor. :-)
Well, that's enough of the "heavy duty" Ansi Coding. For our last example,
lets have some fun on the screen itself by creating a "kaleidoscope" type of
program using ANSI. Copy the following ABOVE the last routine you pasted into
the TestDoor script:
a=random(,,time("s")) ; se "f1Hello"
gu 27 ; cols=result ; gu 1100468 ; rows=result
do forever until k="q" ; mg ; k=result
row=random(1,rows) ; col=random(1,cols-1)
co=substr("0123456789abcdef",random(1,16),1)
char=d2c(random(32,190))
se ""row";"col"Hc"co||char
end ; tr "1HGood Bye!"
exit
The above will go on forever, until you press the "Q" key on the keyboard.
Being completely random, it produces a mish-mash design on the screen. Here's
another that looks a bit more like the kaleidoscopes you may remember:
a=random(,,time("s")) ; se "f1Hello"
gu 27 ; cols=result ; gu 1100468 ; rows=result
do forever until k="q" ; mg ; k=result
row=random(1,rows%2) ; col=random(2,cols%2)-1
co=substr("0123456789abcdef",random(1,16),1)
char=d2c(random(161,255))
se ""row";"col"Hc"co||char
se ""row";"cols-col"Hc"co||char
se ""rows-row";"col"Hc"co||char
se ""rows-row";"cols-col"Hc"co||char
end ; tr "1HGood Bye!"
exit
The above version chops the visible screen into 4 quadrants, then mirrors
the chosen character into each quadrant as a certain distance from the center
of the screen to create the design.
Lastly, try this version:
a=random(,,time("s")) ; se "f1Hello"
gu 27 ; cols=result ; gu 1100468 ; rows=result
do forever until k="q" ; mg ; k=result
row=random(1,(rows%2)-5) ; col=random(1,(cols%2)-5)-1
co=substr("0123456789abcdef",random(1,16),1)
char=d2c(random(161,255)) ; a=random(1,5)
do i=1 to a
se ""row+i";"col+i"Hc"co||char
se ""row+i";"cols-col-i"Hc"co||char
se ""rows-row-i";"col+i"Hc"co||char
se ""rows-row-i";"cols-col-i"Hc"co||char
end i
end ; tr "1HGood Bye!"
exit
By introducing a second loop to the action, actual strings of characters
are printed to the screen, instead of individual characters. This idea could
be taken even further, perhaps by changing the direction of the string, or
producing strings that weren't necessarily straight lines, but perhaps ones
that curved, etc. open up a plethora of different possibilities.
Well, I've tried to think of as many different ways as possible where you
might use ANSI coding with your ARexx commands to further enhance the programs
you create. It is my sincere hope that some or all of the above material will
prove useful for you in the things that you create.
If you'd like to take any of the previous examples to the next, logical
step, but still aren't quite sure how to proceed, feel free to contact me with
any questions you may have. I will definately have wanted you to have read
through this document, and have at least gotten some sort of framework laid
out, but will gladly give you the next building block towards your finished
creation! :-)
Here's how I may be contacted:
Through Internet EMail: dotoran@bluemoon.net
Through World Wide Web: http://www.bluemoon.net/~dotoran
Through FidoNet Network: dotoran@1:260/121.0
Through CLink Network: dotoran@911:6840/2.0
Through Snail Mail: David M. Weeks
318 Woodside Avenue
Buffalo, NY 14220-2015
ATTN: Dotoran
If you feel what you need to ask could be of public interest, you can post
a message, addressed to Dotoran, to one of the following messaging echoes:
The CNET and CNET_BBS message echoes of FidoNet.
The CLINKCNETAMIGA and CLINKCNETPROG message echoes of CLink.
The "CNet Mailing List" on the Internet.
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Created using CED by Dotoran of Frontiers BBS (716)/823-9892!
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-